home *** CD-ROM | disk | FTP | other *** search
- (herald (back_end m682arithgen)
- (env t (orbit_top defs) (back_end bookkeep)))
-
- (define (generate-two-fixnums node compare?)
- (destructure (((then else () ref1 ref2) (call-args node)))
- (let ((val1 (leaf-value ref1))
- (reg2 (let ((reg (get-register 'scratch node '*)))
- (generate-move (access-with-rep node (leaf-value ref2)
- 'rep/pointer) reg)
- reg)))
- (lock reg2)
- (let ((reg1 (let ((reg (get-register 'scratch node '*)))
- (generate-move (access-with-rep node val1
- 'rep/pointer)
- reg)
- reg)))
- (unlock reg2)
- (generate-move reg1 SCRATCH)
- (if (variable? (leaf-value ref2))
- (emit m68/or .w reg2 SCRATCH))
- (emit m68/and .b (machine-num 3) SCRATCH)
- (emit-jump jump-op/jn= else then)
- (or compare?
- (destructure (((arg1 arg2) (lambda-variables then)))
- (mark arg1 reg1)
- (mark arg2 reg2)))))))
-
- (define (generate-op-with-overflow node op)
- (destructure (((then else () ref1 ref2) (call-args node)))
- (let ((reg1 (register-loc (leaf-value ref1)))
- (reg2 (register-loc (leaf-value ref2))))
- (xcase op
- ((add) (emit m68/add .l reg2 reg1))
- ((subtract) (emit m68/sub .l reg2 reg1))
- ((multiply)
- (emit m68/asr .l ($ 2) reg1)
- (emit m68/mulsl reg2 reg1)))
- (emit-jump jump-op/overflow then else)
- (kill (leaf-value ref1))
- (kill (leaf-value ref2))
- (mark (car (lambda-variables else)) reg1))))
-
- (define (generate-hack-dr node op)
- (destructure (((#f ref1 ref2) (call-args node)))
- (let ((reg1 (register-loc (leaf-value ref1)))
- (reg2 (register-loc (leaf-value ref2))))
- (xcase op
- ; ((divide)
- ; (emit m68/divsl reg2 scratch reg1)
- ; (emit m68/asl .l ($ 2) reg1))
- ((remainder)
- (emit m68/divsl reg2 scratch reg1)
- (generate-move scratch reg1)))
- (kill (leaf-value ref1))
- (kill (leaf-value ref2))
- (mark-continuation node reg1))))
-
-
- (define-constant (opposite rep)
- (case rep
- ((rep/pointer) 'rep/integer)
- (else 'rep/pointer)))
-
- (define-constant (same rep)
- (if (eq? rep 'rep/pointer) rep 'rep/integer))
-
- (define (generate-fixnum-multiply node)
- (destructure (((cont right left) (call-args node)))
- (let ((lvar (leaf-value left))
- (rvar (leaf-value right)))
- (receive (t-spec t-rep) (continuation-wants cont)
- (receive (l-rep r-rep)
- (case t-rep
- ((rep/pointer)
- (cond ((variable? lvar)
- (case (variable-rep lvar)
- ((rep/pointer)
- (if (and (variable? rvar)
- (eq? (variable-rep rvar) 'rep/pointer)
- (let ((loc (register-loc lvar)))
- (and (register? loc)
- (eq? (reg-type loc) 'scratch))))
- (return 'rep/integer 'rep/pointer)
- (return 'rep/pointer 'rep/integer)))
- (else
- (return 'rep/integer 'rep/pointer))))
- (else
- (return (opposite (variable-rep rvar))
- (same (variable-rep rvar))))))
- (else
- (return 'rep/integer 'rep/integer)))
- (let ((l-acc (access-with-rep node lvar l-rep)))
- (protect-access l-acc)
- (let ((r-acc (access-with-rep node rvar r-rep)))
- (cond ((and (register? l-acc)
- (eq? (reg-type l-acc) 'scratch)
- (dying? lvar node))
- (cond ((and (register? r-acc)
- (eq? (reg-type r-acc) 'pointer))
- (generate-move r-acc SCRATCH)
- (emit m68/mulsl SCRATCH l-acc))
- (else
- (emit m68/mulsl r-acc l-acc)))
- (release-access l-acc)
- (kill lvar)
- (mark-continuation node l-acc))
- ((and (register? r-acc)
- (eq? (reg-type r-acc) 'scratch)
- (dying? rvar node))
- (cond ((and (register? l-acc)
- (eq? (reg-type l-acc) 'pointer))
- (generate-move l-acc SCRATCH)
- (emit m68/mulsl SCRATCH r-acc))
- (else
- (emit m68/mulsl l-acc r-acc)))
- (release-access l-acc)
- (kill rvar)
- (mark-continuation node r-acc))
- (else
- (let ((t-reg (if (and (register? t-spec)
- (eq? (reg-type t-spec) 'scratch)
- (maybe-free t-spec cont))
- t-spec
- (get-register 'scratch node '*))))
- (release-access l-acc)
- (generate-move r-acc t-reg)
- (cond ((and (register? l-acc)
- (eq? (reg-type l-acc) 'pointer))
- (generate-move l-acc SCRATCH)
- (emit m68/mulsl SCRATCH t-reg))
- (else
- (emit m68/mulsl l-acc t-reg)))
- (mark-continuation node t-reg)))))))))))
-
- (define (generate-fixnum-divide node)
- (generate-fixnum-dr node 'divide))
-
- (define (generate-fixnum-remainder node)
- (generate-fixnum-dr node 'remainder))
-
- (define (generate-fixnum-dr node which)
- (destructure (((cont right left) (call-args node)))
- (receive (t-spec t-rep) (continuation-wants cont)
- (let* ((lvar (leaf-value left))
- (rvar (leaf-value right))
- (l-acc (access-with-rep node lvar 'rep/integer)))
- (protect-access l-acc)
- (let ((r-acc (access-with-rep node rvar 'rep/integer)))
- (release-access l-acc)
- (cond ((and (register? r-acc)
- (dying? rvar node))
- (xcase which
- ((divide)
- (emit m68/divsl l-acc SCRATCH r-acc))
- ((remainder)
- (emit m68/divsl l-acc SCRATCH r-acc)
- (generate-move SCRATCH r-acc)))
- (if (eq? t-rep 'rep/pointer)
- (emit m68/asl .l (machine-num 2) r-acc))
- (kill rvar)
- (mark-continuation node r-acc))
- (else
- (protect-access l-acc)
- (xcase (cond ((register? t-spec) (reg-type t-spec))
- (else t-spec))
- ((scratch *)
- (let ((t-reg (if (and (register? t-spec)
- (not (reg-node t-spec)))
- t-spec
- (get-register 'scratch node '*))))
- (release-access l-acc)
- (generate-move r-acc t-reg)
- (xcase which
- ((divide)
- (emit m68/divsl l-acc SCRATCH t-reg))
- ((remainder)
- (emit m68/divsl l-acc SCRATCH t-reg)
- (generate-move SCRATCH t-reg)))
- (if (eq? t-rep 'rep/pointer)
- (emit m68/asl .l (machine-num 2) t-reg))
- (mark-continuation node t-reg)))
- ((pointer)
- (let* ((t-reg (if (and (register? t-spec)
- (not (reg-node t-spec)))
- t-spec
- (get-register 'pointer node '*)))
- (extra (if (eq? which 'remainder)
- (get-register 'scratch node '*)
- SCRATCH)))
- (release-access l-acc)
- (generate-move r-acc SCRATCH)
- (xcase which
- ((divide)
- (emit m68/divsl l-acc SCRATCH SCRATCH))
- ((remainder)
- (emit m68/divsl l-acc extra SCRATCH)))
- (emit m68/asl .l (machine-num 2) extra)
- (generate-move extra t-reg)
- (mark-continuation node t-reg)))))))))))
-
-
-